package imageGenerator;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

import static drawArrow.DrawArrow.traverseFolder;

/**
 * @projectName: esl-test-frame
 * @className: ImageGenerator
 * @description: 测试图片生成类。输入价签类型，生成基本测试图片
 * @author: JLONG
 * @date: 2024/8/12 13:25
 * @version: 1.0
 */
public class ImageGenerator {

    public static void main(String[] args) {
        String labelTypeFile = "/Users/jlong/IdeaProjects/code-snippet/src/main/java/imageGenerator/labelType.xlsx";
        String outputDir = "/Users/jlong/IdeaProjects/testImages";
        ImageGenerator imageGenerator = new ImageGenerator(labelTypeFile);
//        imageGenerator.generateTestImage("2.6 BW");
        for (String labelType : imageGenerator.labelBeenMap.keySet()) {
            imageGenerator.generateTestImage(labelType);
        }

        traverseFolder(new File(outputDir));
    }

    public Map<String, LabelBeen> labelBeenMap = new HashMap<>();

    public ImageGenerator(String excelPath) {
        try {
            FileInputStream fis = new FileInputStream(new File(excelPath));
            Workbook workbook = new XSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                if (row.getRowNum() == 0) {
                    continue;
                }
                Cell labelTypeCell = row.getCell(0);
                Cell labelPropertyCell = row.getCell(1);
                Cell labelColorCell = row.getCell(2);
                String labelTypeName = labelTypeCell.getStringCellValue();
                String labelProperty = labelPropertyCell.getStringCellValue();
                String labelColor = labelColorCell.getStringCellValue();
                LabelBeen labelBeen = checkLabelBeenIsUnique(this.getLabelType(labelTypeName, labelProperty, labelColor));
                this.labelBeenMap.put(labelBeen.getLabelType(), labelBeen);
            }
            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private LabelBeen checkLabelBeenIsUnique(LabelBeen labelBeen) {
        String labelTypeName = labelBeen.getLabelType();
        int repeatCount = 1;
        for (LabelBeen var : this.labelBeenMap.values()) {
            if (labelBeen.getLabelType().equals(var.getLabelType()) && (labelBeen.getHeight() != var.getHeight())) {
                repeatCount++;
            }
        }
        if (repeatCount > 1) {
            labelBeen.setLabelType(labelTypeName + "_" + repeatCount);
        }

        return labelBeen;
    }

    private void generateTestImage(String labelType) {
        Set<String> keysArray = this.labelBeenMap.keySet();
        if (keysArray.contains(labelType)) {
            LabelBeen varLabel = this.labelBeenMap.get(labelType);
            generateImageByType(varLabel);
        } else {
            System.out.println("对不起，暂缺价签 \"" + labelType + "\" 的相关配置，无法生成图片");
        }
    }

    private void generateImageByType(LabelBeen labelBeen) {
        String colors = labelBeen.getColor();
        List<Pattern> patterns = new ArrayList<>();
        switch (colors) {
            case "MONOCHROM":
                patterns.add(Pattern.WHITE);
                patterns.add(Pattern.BLACK);
                patterns.add(Pattern.BIT_CHECKERED);
                patterns.add(Pattern.BYTE_CHECKERED);
                patterns.add(Pattern.CHECKERED_16_PIXEL);
                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_MONOCHROM);
                patterns.add(Pattern.RANDOM_BLACK_WHITE);
                break;
            case "BLACK_WHITE_RED":
                patterns.add(Pattern.WHITE);
//                patterns.add(Pattern.BLACK);
//                patterns.add(Pattern. BIT_CHECKERED);
//                patterns.add(Pattern.BYTE_CHECKERED);
//                patterns.add(Pattern.CHECKERED_16_PIXEL);
//                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_MONOCHROM);
//                patterns.add(Pattern.RANDOM_BLACK_WHITE);
                patterns.add(Pattern.RED);
                patterns.add(Pattern.HORIZONTAL_BLACK_RED_WHITE);
                patterns.add(Pattern.VERTICAL_BLACK_RED_WHITE);
//                patterns.add(Pattern.BIT_CHECKERED_RED_WHITE);
//                patterns.add(Pattern.BIT_CHECKERED_RED_BLACK);
//                patterns.add(Pattern.BYTE_CHECKERED_RED_WHITE);
//                patterns.add(Pattern.BYTE_CHECKERED_RED_BLACK);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_RED_WHITE);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_RED_BLACK);
//                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_BLACK_WHITE_RED);
                patterns.add(Pattern.RANDOM_BLACK_WHITE_RED);
                break;
            case "BLACK_WHITE_YELLOW":
                patterns.add(Pattern.WHITE);
//                patterns.add(Pattern.BLACK);
//                patterns.add(Pattern. BIT_CHECKERED);
//                patterns.add(Pattern.BYTE_CHECKERED);
//                patterns.add(Pattern.CHECKERED_16_PIXEL);
//                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_MONOCHROM);
//                patterns.add(Pattern.RANDOM_BLACK_WHITE);
                patterns.add(Pattern.YELLOW);
                patterns.add(Pattern.HORIZONTAL_BLACK_YELLOW_WHITE);
                patterns.add(Pattern.VERTICAL_BLACK_YELLOW_WHITE);
//                patterns.add(Pattern.BIT_CHECKERED_YELLOW_WHITE);
//                patterns.add(Pattern.BIT_CHECKERED_YELLOW_BLACK);
//                patterns.add(Pattern.BYTE_CHECKERED_YELLOW_WHITE);
//                patterns.add(Pattern.BYTE_CHECKERED_YELLOW_BLACK);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_YELLOW_WHITE);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_YELLOW_BLACK);
//                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_BLACK_WHITE_YELLOW);
                patterns.add(Pattern.RANDOM_BLACK_WHITE_YELLOW);
                break;
            case "BLACK_WHITE_RED_YELLOW":
                patterns.add(Pattern.WHITE);
//                patterns.add(Pattern.BLACK);
//                patterns.add(Pattern. BIT_CHECKERED);
//                patterns.add(Pattern.BYTE_CHECKERED);
//                patterns.add(Pattern.CHECKERED_16_PIXEL);
//                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_MONOCHROM);
                patterns.add(Pattern.RANDOM_BLACK_WHITE);
                patterns.add(Pattern.RED);
//                patterns.add(Pattern.HORIZONTAL_BLACK_RED_WHITE);
//                patterns.add(Pattern.VERTICAL_BLACK_RED_WHITE);
//                patterns.add(Pattern.BIT_CHECKERED_RED_WHITE);
//                patterns.add(Pattern.BIT_CHECKERED_RED_BLACK);
//                patterns.add(Pattern.BYTE_CHECKERED_RED_WHITE);
//                patterns.add(Pattern.BYTE_CHECKERED_RED_BLACK);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_RED_WHITE);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_RED_BLACK);
//                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_BLACK_WHITE_RED);
                patterns.add(Pattern.RANDOM_BLACK_WHITE_RED);
                patterns.add(Pattern.YELLOW);
                patterns.add(Pattern.HORIZONTAL_BLACK_WHITE_RED_YELLOW);
                patterns.add(Pattern.VERTICAL_BLACK_WHITE_RED_YELLOW);
//                patterns.add(Pattern.BIT_CHECKERED_YELLOW_WHITE);
//                patterns.add(Pattern.BIT_CHECKERED_YELLOW_BLACK);
//                patterns.add(Pattern.BYTE_CHECKERED_YELLOW_WHITE);
//                patterns.add(Pattern.BYTE_CHECKERED_YELLOW_BLACK);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_YELLOW_WHITE);
//                patterns.add(Pattern.CHECKERED_16_PIXEL_YELLOW_BLACK);
//                patterns.add(Pattern.TESTPATTERN_FOR_MEASUREMENTS_BLACK_WHITE_YELLOW);
                patterns.add(Pattern.RANDOM_BLACK_WHITE_RED_YELLOW);
                patterns.add(Pattern.BWRY_8BIT_CHECK);
                break;
        }

        for (Pattern pattern : patterns) {
            generateImage(labelBeen, pattern, -1);
        }

    }

    private LabelBeen getLabelType(String labelTypeName, String labelProperty, String labelColor) {
        LabelBeen labelBeen = new LabelBeen();
        labelBeen.setLabelType(labelTypeName);
        String[] var1 = labelProperty.replace(" ", "").split("[×,]");
        labelBeen.setHeight(Integer.parseInt(var1[0]));
        labelBeen.setWidth(Integer.parseInt(var1[1]));
//        labelType.setPpi(Integer.parseInt(var1[2].substring(0, 3)));
        labelBeen.setColor(labelColor);

        return labelBeen;
    }

    private void generateImage(LabelBeen labelBeen, Pattern pattern, int pageNo) {
        generateImage(labelBeen.getLabelType(), labelBeen.getHeight(), labelBeen.getWidth(), pattern, pageNo);
    }

    private void generateImage(String labelType, int width, int height, Pattern pattern, int pageNo) {
        // 创建一个BufferedImage对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        WritableRaster raster = image.getRaster();
        pattern.updateRaster(raster, 3, width, height);
        // 根据配置，生成图片文件名称
        String imageName;
        if (pageNo == -1) {
            if( labelType.equals("1.6 BWRY E5") || labelType.equals("3.5 BWR")){
                imageName = labelType + "_" + formatPatternName(pattern.name()) + ".png";
            }else{
                imageName = /*labelType + "_" + */formatPatternName(pattern.name()) + ".png";
            }
        } else {
            imageName = "page_" + pageNo + ".png";
        }
        // 将图片保存到文件
        File imagesDir = new File("../testImages/" + labelType + "/");
        if (!imagesDir.exists()) {
            imagesDir.mkdirs();
        }
        File outputFile = new File(imagesDir, imageName);
        try {
            ImageIO.write(image, "png", outputFile);
            System.out.println("生成图片 " + imageName);
        } catch (IOException e) {
            System.out.println("Error:" + e.getMessage());
        }
    }

    private String formatPatternName(String patternName) {
        String newName = patternName;
        switch (patternName) {
            case "HORIZONTAL_BLACK_RED_WHITE":
                newName = "H_B_W_R";
                break;
            case "HORIZONTAL_BLACK_YELLOW_WHITE":
                newName = "H_B_W_Y";
                break;
            case "HORIZONTAL_BLACK_WHITE_RED_YELLOW":
                newName = "H_B_W_R_Y";
                break;
            case "VERTICAL_BLACK_RED_WHITE":
                newName = "V_B_W_R";
                break;
            case "VERTICAL_BLACK_YELLOW_WHITE":
                newName = "V_B_W_Y";
                break;
            case "VERTICAL_BLACK_WHITE_RED_YELLOW":
                newName = "V_B_W_R_Y";
                break;
            case "BIT_CHECKERED":
                newName = "BIT_B_W";
                break;
            case "BIT_CHECKERED_RED_WHITE":
                newName = "BIT_R_W";
                break;
            case "BIT_CHECKERED_YELLOW_WHITE":
                newName = "BIT_Y_W";
                break;
            case "BIT_CHECKERED_RED_BLACK":
                newName = "BIT_R_B";
                break;
            case "BIT_CHECKERED_YELLOW_BLACK":
                newName = "BIT_Y_B";
                break;
            case "BYTE_CHECKERED":
                newName = "BYTE_B_W";
                break;
            case "BYTE_CHECKERED_RED_WHITE":
                newName = "BYTE_R_W";
                break;
            case "BYTE_CHECKERED_YELLOW_WHITE":
                newName = "BYTE_Y_W";
                break;
            case "BYTE_CHECKERED_RED_BLACK":
                newName = "BYTE_R_B";
                break;
            case "BYTE_CHECKERED_YELLOW_BLACK":
                newName = "BYTE_Y_B";
                break;
            case "CHECKERED_16_PIXEL":
                newName = "16_PIXEL_B_W";
                break;
            case "CHECKERED_16_PIXEL_RED_WHITE":
                newName = "16_PIXEL_R_W";
                break;
            case "CHECKERED_16_PIXEL_YELLOW_WHITE":
                newName = "16_PIXEL_Y_W";
                break;
            case "CHECKERED_16_PIXEL_RED_BLACK":
                newName = "16_PIXEL_R_B";
                break;
            case "CHECKERED_16_PIXEL_YELLOW_BLACK":
                newName = "16_PIXEL_Y_B";
                break;
            case "TESTPATTERN_FOR_MEASUREMENTS_MONOCHROM":
                newName = "TEST_B_W";
                break;
            case "TESTPATTERN_FOR_MEASUREMENTS_BLACK_WHITE_RED":
                newName = "TEST_B_W_R";
                break;
            case "TESTPATTERN_FOR_MEASUREMENTS_BLACK_WHITE_YELLOW":
                newName = "TEST_B_W_Y";
                break;
            case "RANDOM_BLACK_WHITE":
                newName = "RANDOM_B_W";
                break;
            case "RANDOM_BLACK_WHITE_RED":
                newName = "RANDOM_B_W_R";
                break;
            case "RANDOM_BLACK_WHITE_YELLOW":
                newName = "RANDOM_B_W_Y";
                break;
            case "RANDOM_BLACK_WHITE_RED_YELLOW":
                newName = "RANDOM_B_W_R_Y";
                break;

        }
        return newName;
    }

}
